package main

import (
	"bufio"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/sevlyar/go-daemon"
	swaggerFiles "github.com/swaggo/files"
	ginSwagger "github.com/swaggo/gin-swagger"
	"go.uber.org/zap"
	"golang.org/x/term"
	"log"
	"os"
	"os/signal"
	"syscall"
	"virus-proxy/cmd/routes"
	"virus-proxy/internal/config"
	"virus-proxy/internal/logger"
	"virus-proxy/internal/mount"
	"virus-proxy/internal/vendor_api/client"
)

func getCredentials() (string, string) {
	// 接收用户名和密码用于挂载cifs共享
	var username, password string
	fmt.Print("Enter UserName and Domain(if exists): ")

	scanner := bufio.NewScanner(os.Stdin)
	fmt.Print("Enter UserName: ")
	scanner.Scan()
	username = scanner.Text()
	//fmt.Println("username", username)

	// 将用户名写入到 user 文件中
	err := os.WriteFile("AVAgentUser", []byte(username+"\n"), 0644)
	if err != nil {
		log.Fatalf("Error writing to user file: %v", err)
	}

	fmt.Print("Enter Password: ")
	passwordByte, err := term.ReadPassword(syscall.Stdin) // 输入时隐藏
	if err != nil {
		log.Fatalf("Error read username: %v", err)
	}
	password = string(passwordByte)
	//fmt.Println("password", password)
	return username, password
}

func main() {
	var user string
	var pw string
	var envVars []string
	if !daemon.WasReborn() {
		user, pw = getCredentials()
		// get list of current env to pass to child process
		var currEnv []string
		for _, e := range os.Environ() {
			currEnv = append(currEnv, e)
		}

		// add token value for child process to read
		envVars = append(currEnv, "MOUNT_USER="+user)
		envVars = append(envVars, "MOUNT_PASS="+pw)
	} else {
		user = os.Getenv("MOUNT_USER")
		pw = os.Getenv("MOUNT_PASS")
	}
	context := &daemon.Context{
		PidFileName: "AVAgent.pid",
		PidFilePerm: 0644,
		LogFileName: "AVAgentDaemon.log",
		LogFilePerm: 0644,
		WorkDir:     "./",
		Umask:       027,
		Env:         envVars,
		Args:        os.Args,
	}
	//os.Stdin.Close()
	child, err := context.Reborn()
	if err != nil {
		log.Fatal("Fail to create AVAgent daemon ", err)
	}
	if child != nil {
		log.Println("Parent process exit,child process pid:", child.Pid)
		return
	}
	defer context.Release()
	setupSignalHandler()
	runDaemon(user, pw)
	//runDaemon("username", "passwd")

}

func runDaemon(username string, passwd string) {
	mount.InitDO(username, passwd)
	// 加载配置文件
	//cfg, err := config.LoadConfig(filepath.Join(exPath, "config.json"))
	cfg, err := config.LoadConfig("config.json")
	if err != nil {
		//OutputDebugString("Error loading config: " + err.Error())
		log.Fatalf("Error loading config: %v", err)
	}
	// 初始化
	logger.InitLogger(cfg.LogLevel)
	err = mount.UpdateMount()
	if err != nil {
		log.Fatal("Failed to init mount array.", zap.Error(err))
		//OutputDebugString("Failed to init mount array.")
	}

	// 启动Gin Web服务
	gin.SetMode(gin.ReleaseMode)
	r := gin.New()
	r.Use(logger.GinLogger(), logger.GinRecovery(true))

	// 监听NAS请求，创建代理
	proxy := client.NewProxy(cfg.ControlCenterIP, cfg.ControlCenterPort, cfg.Vendor, cfg.SecretID, cfg.SecretKey)

	// 挂载设备路径
	r.POST("/mountPoint", routes.MountPoint())
	// 执行扫描任务
	r.POST("/scan", routes.ScanTask(proxy))
	//r.POST("/scanQAX", routes.ScanQAX())
	r.POST("/list", routes.ListMountPoint())
	r.POST("/unMount", routes.UnMountPoint())
	r.POST("/realTimeScan", routes.ScanRealTimeTask(proxy))
	//添加swagger访问路由
	r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))

	// 启动Gin服务器（非阻塞方式运行）
	err = r.Run(":" + cfg.Port)
	if err != nil {
		log.Fatal("Failed to start server.", zap.Error(err))
	}
}

// 处理退出信号
func setupSignalHandler() {
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGTERM, syscall.SIGINT)

	go func() {
		sig := <-sigChan
		log.Print("receive signal , graceful exit...", zap.Any("signal", sig))
		os.Exit(0)
	}()
}
